package elasticsearch

import (
	"class_rpc/internal/model/mysql"
	"encoding/json"
	"fmt"
	"github.com/olivere/elastic/v7"
	"strconv"
)

const mapping = `
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "analysis": {
      "analyzer": {
        "ik_smart_analyzer": {
          "type": "custom",
          "tokenizer": "ik_max_word"
        },
        "ik_max_word_analyzer": {
          "type": "custom",
          "tokenizer": "ik_max_word"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_max_word"
      }
    }
  }
}`

// 创建索引
func IndexClass(indexName string) {
	exists, err := esClient.IndexExists(indexName).Do(ctx)
	if err != nil {
		// Handle error
		panic(err)
	}
	if !exists {
		// Create a new index.
		createIndex, err := esClient.CreateIndex(indexName).BodyString(mapping).Do(ctx)
		if err != nil {
			// Handle error
			panic(err)
		}
		fmt.Println(createIndex)
	}
}

// mysql到Es
func EsByMysql(indexName string) {
	var class []mysql.Class
	mysql.DB.Model(&mysql.Class{}).Offset(0).Limit(20).Find(&class)
	bulk := esClient.Bulk()
	for _, v := range class {
		res := elastic.NewBulkIndexRequest().Index(indexName).Id(strconv.Itoa(int(v.ID))).Doc(v)
		bulk = bulk.Add(res)
	}
	_, err = bulk.Do(ctx)
	if err != nil {
		return
	}
}

// es搜索
func EsSearch(indexName string, termQuery *elastic.TermQuery, offset int, limit int) (int64, []mysql.Class, error) {
	searchResult, err := esClient.Search().
		Index(indexName). // search in index "twitter"
		Query(termQuery). // specify the query
		//Sort("user", true). // sort by "user" field, ascending
		From(offset).Size(limit). // take documents 0-9
		Highlight(elastic.NewHighlight().Field("title").PreTags("<span style='color:red'>").PostTags("<span/>")).
		Pretty(true). // pretty print request and response JSON
		Do(ctx)       // execute
	if err != nil {
		// Handle error
		return 0, nil, err
	}
	var class []mysql.Class
	if searchResult.Hits.TotalHits.Value > 0 {
		// Iterate through results
		for _, hit := range searchResult.Hits.Hits {
			// hit.Index contains the name of the index
			// Deserialize hit.Source into a Tweet (could also be just a map[string]interface{}).
			var t mysql.Class
			err := json.Unmarshal(hit.Source, &t)
			if err != nil {
				return 0, nil, err
			}
			class = append(class, t)
		}
	} else {

		return 0, nil, err
	}
	return searchResult.Hits.TotalHits.Value, class, err
}
